package com.cc.data_explore.gui.tab;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cc.data_explore.logic.data.AnalysisTableData;
import com.cc.data_explore.logic.mybatis.DbHelper;
import com.cc.data_explore.logic.mybatis.mapper.sub.AnalysisTableMapper;
import com.cc.data_explore.logic.mybatis.mapper.sub.TableConfigMapper;
import com.cc.data_explore.logic.mybatis.model.TableConfig;
import de.saxsys.mvvmfx.ViewModel;
import io.datafx.core.concurrent.ProcessChain;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import lombok.Getter;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.math.NumberUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.JSONUtil;

import java.lang.invoke.VarHandle;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * CatImportDataDialogViewModel
 *
 * @author aa
 * @version 1.0
 * @since 2025/4/10
 */
@Getter
public class CatImportDataDialogViewModel implements ViewModel {

    private final SimpleIntegerProperty total = new SimpleIntegerProperty(0);
    private final IntegerProperty pageNum = new SimpleIntegerProperty(1);
    private final IntegerProperty pageSize = new SimpleIntegerProperty(10);

    private final ObservableList<Map<String, Object>> items = FXCollections.observableArrayList();

    private final ObservableMap<String, String> columnMap = FXCollections.observableMap(new LinkedHashMap<>());

    private final StringProperty tableName = new SimpleStringProperty();

    public void initialize() {
        SqlSessionFactory sqlSessionFactory = DbHelper.getInstance().getSqlSessionFactory();
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            TableConfigMapper mapper = sqlSession.getMapper(TableConfigMapper.class);
            TableConfig tc = mapper.selectOne(Wrappers.emptyWrapper());
            if (tc != null) {
                tableName.set(tc.getTableNameEn());
                String headList = tc.getHeadList();
                List<AnalysisTableData> analysisTableDataList = JSONUtil.toList(headList, AnalysisTableData.class);
                analysisTableDataList.forEach(tableData -> columnMap.put(tableData.getTableFieldZh(), tableData.getTableFieldEn()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void loadData() {
        if (StrUtil.isEmpty(tableName.get())) {
            return;
        }
        SqlSessionFactory sqlSessionFactory = DbHelper.getInstance().getSqlSessionFactory();
        ProcessChain.create().addRunnableInPlatformThread(items::clear)
                .addSupplierInExecutor(() -> {
                    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
                        AnalysisTableMapper analysisTableMapper = sqlSession.getMapper(AnalysisTableMapper.class);
                        String sql = "select * from " + tableName.get();
                        System.out.println(getPageNum());
                        return analysisTableMapper.selectMapsPage(Page.of(getPageNum()+1, getPageSize()), sql);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                })
                .addConsumerInPlatformThread(r -> {
                    totalProperty().set(NumberUtil.parseInt(r.getTotal() + ""));
                    items.addAll(r.getRecords());
                }).onException(Throwable::printStackTrace).run();
    }

    public int getTotal() {
        return total.get();
    }

    public SimpleIntegerProperty totalProperty() {
        return total;
    }

    public int getPageNum() {
        return pageNum.get();
    }

    public IntegerProperty pageNumProperty() {
        return pageNum;
    }

    public int getPageSize() {
        return pageSize.get();
    }

    public IntegerProperty pageSizeProperty() {
        return pageSize;
    }
}
